# !/usr/bin/env python
# -*- coding:utf-8 -*-
# @FileName  :user.py
# @Time      :2022/7/10 16:00
# @Author    :吕华龙
import os
import random

import redis
from qiniu import Auth, put_file

from fields_all import article_fields, user_fields
from flask import Blueprint, jsonify, g, request
from flask_restful import Api, Resource, reqparse, marshal
from utils.jwt_tool import Jwt_Tool
from utils.qiniu_upload import QiniuTool

from models.model import User, db, Article
from utils.send_sms import send_message

user_bp = Blueprint("user_bp", __name__, url_prefix="/user")

api = Api(user_bp)


# s使用钩子函数和装饰器强制登录
def Login_gz():
    resp = reqparse.RequestParser()
    resp.add_argument("token", default="", location="headers")
    args = resp.parse_args()
    j = Jwt_Tool()

    payload = j.ver_token(args['token'])

    if not payload:
        payload = None
    g.user = payload


def required_login(func):
    def warpper(*args, **kwargs):
        if not g.user:
            return jsonify({'code': 403, 'msg': '用户未登录'})
        return func(*args, **kwargs)

    return warpper


# 发送验证码
class SendSmsCode(Resource):
    def post(self):
        resp = reqparse.RequestParser()
        resp.add_argument("mobile")
        args = resp.parse_args()
        code = random.randint(10000, 99999)

        exp = 300
        # 请求容联云发送验证码
        res = send_message(args['mobile'], code, exp)
        # 如果有就是发送成功了，c存入Redis
        if res:
            redis_cli = redis.Redis(host="localhost", port=6379, db=4, password=123)
            redis_cli.set(args['mobile'], code, ex=300)

            return jsonify({'code': 200, 'msg': '发送成功', 'sms': code})
        else:
            return jsonify({'code': 400, 'msg': '发送失败'})


# 注册登录
class Login(Resource):
    def post(self):
        resp = reqparse.RequestParser()
        resp.add_argument("mobile")
        resp.add_argument("code")
        args = resp.parse_args()

        # 判断用户是否完整信息
        if not all([args['mobile'], args['code']]):
            return jsonify({'code': 400, 'msg': '请填写完整信息'})

        redis_cli = redis.Redis(host="localhost", port=6379, db=4, password=123)
        # user_info = User.query.filter(User.mobile == args['mobile']).first()
        # if user_info:
        if not redis_cli.get(args['mobile']):
            return jsonify({'code': 400, 'msg': '验证码已过期'})
        if args['code'] != redis_cli.get(args['mobile']).decode():
            return jsonify({'code': 400, 'msg': '验证码错误'})
        user = User.query.filter(User.mobile == args['mobile']).first()
        if not user:
            user_add = User(mobile=args['mobile'], username=args['mobile'])
            db.session.add(user_add)
            db.session.commit()
            j = Jwt_Tool()
            token = j.create_token({
                "uid": user_add.uid,
                "mobile": user_add.mobile,
            }, 3600)
            return jsonify({'code': 200, 'msg': '注册成功', 'token': token})

        user_info = User.query.filter(User.mobile == args['mobile']).first()
        if user_info:
            j = Jwt_Tool()
            token = j.create_token({
                "uid": user_info.uid,
                "mobile": user_info.mobile,
            }, 3600)
            return jsonify({'code': 200, 'msg': "用户已存在，登录", "token": token})


# 文章视图
class ArticleView(Resource):
    @required_login
    def post(self):
        user_id = g.user["uid"]
        resp = reqparse.RequestParser()
        resp.add_argument("title")
        resp.add_argument("content")
        resp.add_argument("user_id")
        args = resp.parse_args()

        article = Article.query.filter(Article.title == args['title']).first()

        if article:
            return jsonify({'code': 400, 'msg': '此文章已存在不能重复添加'})

        article_info = Article(title=args['title'], content=args['content'], user_id=args['user_id'])

        db.session.add(article_info)
        db.session.commit()
        return jsonify({'code': 200, 'smg': '添加文章成功'})

    @required_login
    def get(self):
        article = Article.query.order_by(Article.bup_time.desc()).all()
        article_marshal = marshal(article, article_fields)
        return jsonify({'code': 200, 'msg': '获取文章列表成功', 'article': article_marshal})

    # 删除文章
    @required_login
    def delete(self):
        uid = g.user['uid']
        resp = reqparse.RequestParser()
        resp.add_argument("aid")
        args = resp.parse_args()

        article = Article.query.filter_by(aid=args['aid']).first()
        if uid == article.user_id:
            Article.query.filter_by(aid=args['aid']).delete()
            db.session.commit()
            return jsonify({'code': 200, 'msg': '删除成功'})
        else:
            article = Article.query.filter_by(user_id=uid).all()
            article_mar = marshal(article, article_fields)
            return jsonify({'code': 403, 'msg': '文章不存在', 'article': article_mar})


# 获取指定的文章
class ArticleInfo(Resource):
    @required_login
    def post(self):
        uid = g.user["uid"]
        resp = reqparse.RequestParser()
        resp.add_argument("aid")
        args = resp.parse_args()
        fiel_name = str(random.randint(10000, 99999)) + str(random.randint(10000, 99999)) + ".png"
        img = request.files.get("img")
        img.save("./static/" + fiel_name)

        ak = "icLlrc9a9eOKxWd9oWWfxrSfCXrGM0Glx7WcdL8e"
        sk = "cMI-8TFzJsGJ3OUPm3jPko5W56qo8T4FtItStAbk"
        auth = Auth(access_key=ak, secret_key=sk)
        bucket_name = "lvhualong1"
        key = fiel_name
        file_path = "./static/" + fiel_name

        token = auth.upload_token(bucket_name, key, 3600)

        # 开始上传
        set, info = put_file(token, key, file_path, version="v2")
        if not set:
            return jsonify({'code': 400, 'msg': '上传图片失败'})
        article_info = Article.query.filter_by(aid=args['aid']).first()
        print("-----------------", article_info, article_info.img)
        article_info.img = key
        db.session.commit()
        return jsonify({'code': 200, 'msg': '上传成功', 'img': set['key']})

    # 5. 图片上传接口，接受图片和文章id,校验用户权限，如果文章是当前用户上传，则直接将图片上传至七牛云。上传完成后，直接修改数据库相应数据行的图片字段的值。并返回json提示：上传成功。如果不是该用户发表的，则直接提示上传失败。
    # @required_login
    # def post(self):
    #     uid = g.user['uid']
    #     # 1. 获取前端数据
    #     resp = reqparse.RequestParser()
    #     resp.add_argument("aid")
    #     args = resp.parse_args()
    #     img = request.files.get("img")
    #
    #     # 2. 为防止sqk注入使用随机生成文件名
    #     n = random.randint(10000000, 99999999)
    #     # 2.1 把生成的图片转换为字符型
    #     n = str(n)
    #     # 2.2 拼接除存放路径
    #     file_path = "./static/" + n + ".png"
    #     img.save(file_path)  # 这一步，相当于把文件存到了本地
    #
    #     # 3. 接下来上传到七牛云
    #     ak = "icLlrc9a9eOKxWd9oWWfxrSfCXrGM0Glx7WcdL8e"
    #     sk = "cMI-8TFzJsGJ3OUPm3jPko5W56qo8T4FtItStAbk"
    #     q = Auth(ak, sk)
    #
    #     # 拼接上传文件名
    #     key = n + ".png"
    #     # 上传到自己的七牛空间      空间名    文件名  过期时间
    #     token = q.upload_token("lvhualong1", key, 3600)
    #
    #     ret, info = put_file(token, key, file_path)
    #
    #     if ret["key"] == key:
    #         article_info = Article.query.filter_by(aid=args['aid']).first()
    #         print('-----------', article_info)
    #         article_info.img = key
    #         db.session.commit()
    #         print("--文件地址", file_path)
    #
    #         return jsonify({"code": 200, "msg": "图片上传成功"})
    #     else:
    #         return jsonify({"code": 400, "msg": "图片上传失败"})

    # @required_login
    # def post(self):
    #     # g对象中获取用户ID
    #     uid = g.user["uid"]
    #     # 获取用户输入
    #     resp = reqparse.RequestParser()
    #     resp.add_argument("aid")
    #     args = resp.parse_args()
    #     img = request.files.get("img")
    #     # 随机生成数字串，防止sql注入
    #     n = random.randint(10000000, 99999999)
    #     # 将字符串转成字符串
    #     n_file = str(n)
    #     # 将随机生成的拼接成路径
    #     file_path = "./static/" + n_file + ".png"
    #     # 将路径保存到目录
    #     img.save(file_path)
    #     # 3. 接下来上传到七牛云
    #     ak = "icLlrc9a9eOKxWd9oWWfxrSfCXrGM0Glx7WcdL8e"
    #     sk = "cMI-8TFzJsGJ3OUPm3jPko5W56qo8T4FtItStAbk"
    #     q = Auth(ak, sk)
    #     # 拼接上传  文件名
    #     key = n_file + ".png"
    #     # 上传到自己的七牛空间    空间名    文件名  过期时间
    #     token = q.upload_token("lvhualong1", key, 3600)
    #     # 用put_file方法串入token和文件名和路径
    #     ret, info = put_file(token, key, file_path)
    #     # 如果文件名一样就在aid 中加入图片
    #     if ret['key'] == key:
    #         article = Article.query.filter_by(aid=args['aid'], user_id=uid)
    #         article.img = key
    #         db.session.commit()
    #         return jsonify({'code': 200, 'msg': '图片上传成功'})
    #     else:
    #         return jsonify({'code': 400, 'msg': '图片上传失败'})

    # @required_login
    # def post(self):
    #     uid = g.user['uid']
    #     # 1. 获取前端数据
    #     resp = reqparse.RequestParser()
    #     resp.add_argument("aid")
    #     args = resp.parse_args()
    #     img = request.files.get("img")
    #     img.save("./static/" + img.filename)
    #
    #     qn = QiniuTool()
    #     file_path = qn.upload_file("./static/" + img.filename, img.filename)
    #
    #     # 存到当前的数据库
    #     try:
    #         Article.query.filter(User.uid == uid).update({"img": file_path})
    #         db.session.commit()
    #         return jsonify({'code': 200, 'msg': '图片上传成功'})
    #     # print(file_path)
    #     except Exception as e:
    #         print(e, "修改头像报错")
    #         return jsonify({'code': 400, 'msg': '上传头像错误'})
    #     # return "上传成功"

    # 获取单条文章
    @required_login
    def get(self):
        print("获取文章")
        uid = g.user.get("uid")
        print("---", uid, g.user)
        resp = reqparse.RequestParser()
        resp.add_argument("aid")
        args = resp.parse_args()
        article = Article.query.filter_by(aid=args['aid'], user_id=uid).first()

        user = User.query.filter_by(uid=uid).first()

        if article:
            user_marshal = marshal(user, user_fields)
            article_mar = marshal(article, article_fields)
            print("----------", article_mar)
            return jsonify({'code': 200, 'msg': '获取成功', 'article': article_mar, "user": user_marshal})

        title_1 = Article.query.filter_by(aid=args['aid']).first()

        if not title_1:
            return jsonify({'code': 400, 'msg': '文章不存在'})

        article_user_id = Article.query.filter_by(user_id=uid).first()
        if uid != article_user_id:
            return jsonify({'code': 403, 'msg': '用户没有权限'})


# 创建路由
api.add_resource(SendSmsCode, "/sms")
# 注册登录
api.add_resource(Login, "/reg_login")
# 文章视图
api.add_resource(ArticleView, "/article")
# 查看指定文章
api.add_resource(ArticleInfo, "/article_info")
